
#include "rasp_simu.h"

Rasp_Simu::Rasp_Simu() {
    Echo_Len = 10000;
    BeamCoe_Len = 20001;
    STargetNum = 2;
    ehobacklen = 0;
    BeamCoePara.DAziRBeamAmp = nullptr;
    BeamCoePara.DEleRBeamAmp = nullptr;
    BeamCoePara.SAziRBeamAmp = nullptr;
    BeamCoePara.SAziTBeamAmp = nullptr;
    BeamCoePara.SEleRBeamAmp = nullptr;
    BeamCoePara.SEleTBeamAmp = nullptr;
    BeamCoePara.SLBAziBeamAmp = nullptr;
    BeamCoePara.SLBEleBeamAmp = nullptr;
    MTargetEchoSig = nullptr;
    TFdCoeAddr = nullptr;
    WorkSig = nullptr;
    EchoData0Addr = nullptr;
    pOut = nullptr;
    m_NoiseRcs = 10;
    sendcount = 0;
    m_CpiNum = 1;
    b_AllfrSame = true;

    m_fFrFs = 2;

    uTargetRCSType_1 = 0;
    uTargetRCSType_2 = 0;
    fTargetRange_1 = 75 * 1e3;
    fTargetRCS_1 = 20;
    fTargetVel_1 = 100;

    fTargetRange_2 = 250 * 1e3;
    fTargetRCS_2 = 30;
    fTargetVel_2 = -100;

    m_uBwBeamNum = 1;
    m_RBeam.fRBeamAzi = 0;
    m_RBeam.fRBeamEle = 0;
    m_RBeam.SubFrFlag[0] = true;
    m_RBeam.uRBeamNo = 0;
    m_RBeam.uRBeamType = 0;

    m_uFrNum = 8;
    m_fFrPt = 4600;
    m_fSubFrBw = 1;
    m_fSubFrFre = 3000;
    m_fSubFrFs = 2;
    m_fSubFrPt = 800;
    m_fSubFrPw = 800;
    m_uSubFrType = 0;
    m_uExpectTime = 0;

    target_count = 0;

    std::random_device rd;
    std::mt19937 mt(rd());
    std::normal_distribution<> normal_dist(0, 1);
    pNoiseData = new std::complex<float>[MaxNoiseLen];
    for (int i = 0; i < MaxNoiseLen; ++i) {
        pNoiseData[i].real(normal_dist(mt));
        pNoiseData[i].imag(normal_dist(mt));
    }
}

Rasp_Simu::~Rasp_Simu() {
    delete[] pNoiseData;
};

bool Rasp_Simu::SetEchoLen(unsigned int len) {
    if (Echo_Len != len) {
        if (MTargetEchoSig != nullptr) {
            delete[]MTargetEchoSig;
            MTargetEchoSig = nullptr;
        }
        if (TFdCoeAddr != nullptr) {
            delete[]TFdCoeAddr;
            TFdCoeAddr = nullptr;
        }
        if (WorkSig != nullptr) {
            delete[]WorkSig;
            WorkSig = nullptr;
        }
        if (EchoData0Addr != nullptr) {
            delete[]EchoData0Addr;
            EchoData0Addr = nullptr;
        }
        if (pOut != nullptr) {
            delete[]pOut;
            pOut = nullptr;
        }
    }
    Echo_Len = len;
    if (MTargetEchoSig == nullptr) {
        MTargetEchoSig = new std::complex<float>[Echo_Len];//开辟目标回波内存,大小64*8MB，根据需要设定
    }
    if (TFdCoeAddr == nullptr) {
        TFdCoeAddr = new std::complex<float>[Echo_Len];//开辟多普勒调制系数内存,大小500K*64bits
    }
    if (WorkSig == nullptr) {
        WorkSig = new std::complex<float>[Echo_Len];//开辟回波数据内存
    }
    if (EchoData0Addr == nullptr) {
        EchoData0Addr = new std::complex<float>[Echo_Len];//开辟回波数据内存
    }
    if (pOut == nullptr) {
        pOut = new std::complex<float>[Echo_Len];//开辟回波输出内存
        double *randtemp;
        randtemp = new double[2000];
        memset(randtemp, 0, 2000 * sizeof(double));
        srand((unsigned) time(nullptr));
        for (int i = 0; i < 2000; i++) {
            randtemp[i] = (double) rand() / RAND_MAX;
        }
        memcpy((char *) rcsswerling, randtemp, 2000 * sizeof(double));
        delete[]randtemp;
        randtemp = nullptr;
        double sum = 0;
        for (int i = 0; i < 2000; i++) {
            sum += rcsswerling[i];
        }
        sum /= 2000;
        for (int i = 0; i < 2000; i++) {
            rcsswerling[i] /= sum;
        }
    }
    return true;
}

bool Rasp_Simu::SetBeamAmpFile(const void *beamampfile) {
    FILE *pfile = nullptr;
    pfile = fopen((char *) beamampfile, "rb+");
    if (pfile == nullptr)
    {
        std::cout << "Open file failed!!!!!!!!!!!" << std::endl;
        return false;
    }

    fread(&BeamCoe_Len, sizeof(int), 1, pfile);

    if (BeamCoePara.SAziTBeamAmp != nullptr) {
        delete[]BeamCoePara.SAziTBeamAmp;
        BeamCoePara.SAziTBeamAmp = nullptr;
    }
    if (BeamCoePara.SEleTBeamAmp != nullptr) {
        delete[]BeamCoePara.SEleTBeamAmp;
        BeamCoePara.SEleTBeamAmp = nullptr;
    }
    if (BeamCoePara.SAziRBeamAmp != nullptr) {
        delete[]BeamCoePara.SAziRBeamAmp;
        BeamCoePara.SAziRBeamAmp = nullptr;
    }
    if (BeamCoePara.SEleRBeamAmp != nullptr) {
        delete[]BeamCoePara.SEleRBeamAmp;
        BeamCoePara.SEleRBeamAmp = nullptr;
    }
    if (BeamCoePara.DAziRBeamAmp != nullptr) {
        delete[]BeamCoePara.DAziRBeamAmp;
        BeamCoePara.DAziRBeamAmp = nullptr;
    }
    if (BeamCoePara.DEleRBeamAmp != nullptr) {
        delete[]BeamCoePara.DEleRBeamAmp;
        BeamCoePara.DEleRBeamAmp = nullptr;
    }
    if (BeamCoePara.SLBAziBeamAmp != nullptr) {
        delete[]BeamCoePara.SLBAziBeamAmp;
        BeamCoePara.SLBAziBeamAmp = nullptr;
    }
    if (BeamCoePara.SLBEleBeamAmp != nullptr) {
        delete[]BeamCoePara.SLBEleBeamAmp;
        BeamCoePara.SLBEleBeamAmp = nullptr;
    }

    BeamCoePara.SAziTBeamAmp = new std::complex<float>[BeamCoe_Len]; //开辟波束方向图的内存
    BeamCoePara.SEleTBeamAmp = new std::complex<float>[BeamCoe_Len]; //开辟波束方向图的内存
    BeamCoePara.SAziRBeamAmp = new std::complex<float>[BeamCoe_Len]; //开辟波束方向图的内存
    BeamCoePara.SEleRBeamAmp = new std::complex<float>[BeamCoe_Len]; //开辟波束方向图的内存
    BeamCoePara.DAziRBeamAmp = new std::complex<float>[BeamCoe_Len]; //开辟波束方向图的内存
    BeamCoePara.DEleRBeamAmp = new std::complex<float>[BeamCoe_Len]; //开辟波束方向图的内存
    BeamCoePara.SLBAziBeamAmp = new std::complex<float>[BeamCoe_Len];    //开辟波束方向图的内存
    BeamCoePara.SLBEleBeamAmp = new std::complex<float>[BeamCoe_Len];    //开辟波束方向图的内存

    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.SAziTBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.SEleTBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.SAziRBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.SEleRBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.DAziRBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.DEleRBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.SLBAziBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    for (int i = 0; i < BeamCoe_Len; i++) {
        fread(BeamCoePara.SLBEleBeamAmp + i, sizeof(std::complex < float > ), 1, pfile);
    }
    fclose(pfile);
    return true;
}

bool Rasp_Simu::SetFrPt(float fpt) {
    m_fFrPt = fpt;
    return true;
}

bool Rasp_Simu::SetFrFs(float ffs) {
    m_fFrFs = ffs;
    return true;
}

bool Rasp_Simu::SetFrNum(unsigned int frnum) {
    m_uFrNum = frnum;
    return true;
}

bool Rasp_Simu::SetSubFrFre(float SubFrFre) {
    m_fSubFrFre = SubFrFre;
    return true;
}

bool Rasp_Simu::SetSubFrFs(float SubFrFs) {
    m_fSubFrFs = SubFrFs;
    return true;
}

bool Rasp_Simu::SetSubFrPt(float SubFrPt) {
    m_fSubFrPt = SubFrPt;
    return true;
}

bool Rasp_Simu::SetSubFrPw(float SubFrPw) {
    m_fSubFrPw = SubFrPw;
    return true;
}

bool Rasp_Simu::SetSubFrBw(float SubFrBw) {
    m_fSubFrBw = SubFrBw;
    return true;
}

bool Rasp_Simu::SetSubFrType(unsigned int SubFrType) {
    m_uSubFrType = SubFrType;
    return true;
}

bool Rasp_Simu::SetTargetRCS1(float TargetRCS1) {
    fTargetRCS_1 = TargetRCS1;
    return true;
}

bool Rasp_Simu::SetTargetRCS2(float TargetRCS2) {
    fTargetRCS_2 = TargetRCS2;
    return true;
}

bool Rasp_Simu::SetTargetRCSType1(unsigned TargetRCSType1) {
    uTargetRCSType_1 = TargetRCSType1;
    return true;
}

bool Rasp_Simu::SetTargetRCSType2(unsigned TargetRCSType2) {
    uTargetRCSType_2 = TargetRCSType2;
    return true;
}

bool Rasp_Simu::SetTargetRange1(float TargetRange1) {
    fTargetRange_1 = TargetRange1;
    return true;
}

bool Rasp_Simu::SetTargetRange2(float TargetRange2) {
    fTargetRange_2 = TargetRange2;
    return true;
}

bool Rasp_Simu::SetTargetVel1(float fTargetVel1) {
    fTargetVel_1 = fTargetVel1;
    return true;
}

bool Rasp_Simu::SetTargetVel2(float fTargetVel2) {
    fTargetVel_2 = fTargetVel2;
    return true;
}

bool Rasp_Simu::SetNoiseRcs(float noisercs) {
    m_NoiseRcs = noisercs;
    return true;
}

bool Rasp_Simu::SetFlagAddNoise(int flag) {
    FlagAddNoise = flag;
    return true;
}

void Rasp_Simu::UnInit() {
    delete[]MTargetEchoSig;
    MTargetEchoSig = nullptr;
    delete[]BeamCoePara.SAziTBeamAmp;
    BeamCoePara.SAziTBeamAmp = nullptr;
    delete[]BeamCoePara.SEleTBeamAmp;
    BeamCoePara.SEleTBeamAmp = nullptr;
    delete[]BeamCoePara.SAziRBeamAmp;
    BeamCoePara.SAziRBeamAmp = nullptr;
    delete[]BeamCoePara.SEleRBeamAmp;
    BeamCoePara.SEleRBeamAmp = nullptr;
    delete[]BeamCoePara.DAziRBeamAmp;
    BeamCoePara.DAziRBeamAmp = nullptr;
    delete[]BeamCoePara.DEleRBeamAmp;
    BeamCoePara.DEleRBeamAmp = nullptr;
    delete[]BeamCoePara.SLBAziBeamAmp;
    BeamCoePara.SLBAziBeamAmp = nullptr;
    delete[]BeamCoePara.SLBEleBeamAmp;
    BeamCoePara.SLBEleBeamAmp = nullptr;
}

bool Rasp_Simu::SetTargetNum(unsigned int TNum) {
    STargetNum = TNum;
    return true;
}

int Rasp_Simu::DataProcess(void *DataIn, int inLen, void *DataOut, int outLen) {
    m_uTarDataLen = CalcuEchoLen();
    if (m_uTarDataLen * sizeof(std::complex < float > ) > Echo_Len) {
        LOG_ERROR("The Echo_Len is not enough for simu echo!");
        return 0;
    }

    if (STargetNum == 0) {
        memset(pOut, 0, sizeof(std::complex < float > ) * m_uTarDataLen);
        return 0;
    }
    memset(pOut, 0, sizeof(std::complex < float > ) * m_uTarDataLen);

    if (target_count == 0) {
        fTargetNowRange1 = fTargetRange_1;
        fTargetNowRange2 = fTargetRange_2;
        fTargetNowVel1 = fTargetVel_1;
        fTargetNowVel2 = fTargetVel_2;
        target_count++;
    }

    for (int i = 0; i < STargetNum; i++) {
        if (i == 0) {
            ehobacklen = Gen_STargetEchoSig(fTargetRCS_1, uTargetRCSType_1, fTargetNowRange1, fTargetVel_1);
        } else if (i == 1) {
            ehobacklen = Gen_STargetEchoSig(fTargetRCS_2, uTargetRCSType_2, fTargetNowRange2, fTargetVel_2);
        }
    }

    //添加噪声
    if (FlagAddNoise > 0) {
        memset(MTargetEchoSig, 0, sizeof(std::complex < float > ) * m_uTarDataLen);

        std::random_device rd;
        std::default_random_engine rde(rd());
        std::uniform_int_distribution<int> uniform_dist(1, 100);
        int mean = uniform_dist(rde);
        memcpy(MTargetEchoSig, pNoiseData + mean * sizeof(std::complex < float > ),
               sizeof(std::complex < float > ) * m_uTarDataLen);

        //噪声幅度10dB
        float Amp = pow(10.0f, (m_NoiseRcs / 20.0f));;
        std::complex<float> alpha;
        alpha.imag(0);
        alpha.real(1);

        for (int i = 0; i < m_uTarDataLen; i++) {
            MTargetEchoSig[i].real(MTargetEchoSig[i].real() * Amp);
            MTargetEchoSig[i].imag(MTargetEchoSig[i].imag() * Amp);
        }

        cblas_caxpy(m_uTarDataLen, reinterpret_cast<float*>(&alpha), reinterpret_cast<float*>(&MTargetEchoSig), 1, reinterpret_cast<float*>(pOut), 1);
    }


//    int perpulselength = m_uTarDataLen / m_uFrNum * sizeof(std::complex<float>);
//    memcpy((char *) DataOut, (char *) pOut + sendcount * perpulselength, perpulselength);

    m_uExpectTime += m_fFrPt * m_uFrNum / 10;

    fTargetNowRange1 = fTargetNowRange1 + fTargetNowVel1 * m_fFrPt * m_uFrNum / 1e6;
    if (fTargetNowRange1 > 500 * 1e3) {
        fTargetNowRange1 = fTargetRange_1;
    }
    if (fTargetNowRange1 < 0) {
        fTargetNowRange1 = fTargetRange_1;
    }

    fTargetNowRange2 = fTargetNowRange2 + fTargetNowVel2 *
                                          m_fFrPt * m_uFrNum / 1e6;
    if (fTargetNowRange2 < 0) {
        fTargetNowRange2 = fTargetRange_2;
    }
    if (fTargetNowRange2 > 500 * 1e3) {
        fTargetNowRange2 = fTargetRange_2;
    }

    memcpy((char *) DataOut, (char *) pOut, m_uTarDataLen * sizeof(std::complex < float > ));
    return m_uTarDataLen;
}

int Rasp_Simu::Gen_STargetEchoSig(float rcs, unsigned int rcs_type, float TargetRange, float fTargetVel) {
    unsigned int uSubFrNum;                                     //脉冲内子脉冲数
    float fFrPt = 0;                                            //脉冲重复周期，单位：us
    float fFrFs = 0;                                            //子脉冲采样带宽，单位：MHz
    float fSubFrFre;                                            //子发射频率，单位：MHz
    float fSubFrPt;                                             //子脉冲重复周期，单位：us
    float fSubFrPw;                                             //子脉冲时宽，单位：us
    float fSubTBeamAzi;                                         //子脉冲发射波束指向方位（阵面坐标系），单位：弧度
    float fSubTBeamEle;                                         //子脉冲发射波束指向俯仰（阵面坐标系），单位：弧度
    unsigned int uScatter_FsCellDelayNum[MaxScatterNum];        //不同散射点整数倍延迟采样单元
    std::complex<float> Scatter_PhaseDelay[MaxScatterNum];      //不同散射点非整数倍相位延迟系数
    unsigned int uPtLen;                                        //重周长度
    unsigned int uPwLen = 0;                                    //脉冲长度
    unsigned int uMSubPtLen;                                    //子脉冲重周长度累加
    float fFsCell;                                              //采样单元长度
    unsigned int uTargetCell;                                   //目标所在采样单元
    float fTargetAmp;
    std::complex<float> TPhaseCell(0, 0);

    unsigned int ZeroLen = 0;                                   //数据补零长度
    float fTPhase = 0;
    float fTFd;                                                 //目标多普勒I/Q
    float fSubTotalTime = 0;                                    //子脉冲内总时间
    float fTotalTime = 0;                                       //总时间
    unsigned int uModifyAddr = 0;

    float fScatterAmp = 0;                                      //散射点幅度

    DBF_RBEAM_STRUCT RBeamTemp;
    memcpy(&RBeamTemp, (char *) &m_RBeam, sizeof(DBF_RBEAM_STRUCT));
    std::complex<float> RBeamCoe;
    std::complex<float> BeamPhase;                              //接收波束对目标的调制系数，和差波束加权系数，根据收发方向图和角度解算目标角度调制信息
    memset(&BeamPhase, 0, sizeof(std::complex < float > ));
    fTargetAmp = pow(10.0f, (rcs / 20.0f));

    fFrFs = m_fFrFs * 1e6;
    fFsCell = C_Speed / (2 * fFrFs);
    for (int i = 0; i < 1; i++) {
        int randnum = rand() % 2000;
        fScatterAmp = pow(10.0f, (0 / 20.0f));
        if (rcs_type == 1 || rcs_type == 3) {
            fScatterAmp *= rcsswerling[randnum];
        }

        uScatter_FsCellDelayNum[i] = floor(
                TargetRange / fFsCell);                                                 //不同散射点整数倍延迟的采样单元
        Scatter_PhaseDelay[i] = ComplexExp(
                2 * Pi * (TargetRange / fFsCell - uScatter_FsCellDelayNum[i]));      //不同散射点非整数倍相位延迟系数
        Scatter_PhaseDelay[i].real(Scatter_PhaseDelay[i].real() * fScatterAmp);
        Scatter_PhaseDelay[i].imag(Scatter_PhaseDelay[i].imag() * fScatterAmp);
    }

    fTotalTime = 0;

    for (int i = 0; i < m_CpiNum; i++)  //脉组循环
    {
        if (b_AllfrSame == 1)           //本脉组内所有脉冲信息固定
        {
            fFrPt = m_fFrPt * 1e-6;
            fFrFs = m_fFrFs * 1e6;
            uSubFrNum = 1;
        }
        for (int j = 0; j < m_uFrNum; j++)//脉组内脉冲循环
        {
            uPwLen = Gen_WorkSig(WorkSig); //往目标所在位置填入回波信号（未加相位、多普勒及距离走动调制等信息)
            fFsCell = C_Speed / (2 * fFrFs);
            uPtLen = floor(fFrFs * fFrPt);    //重复周期采样单元数
            uTargetCell = floor(TargetRange / fFsCell);//计算目标所在采样单元
            //本脉冲内内存初始化为0
            fSubTotalTime = 0.0;
            uMSubPtLen = 0;
            //计算接收波束调制系数
            memset(TFdCoeAddr, 0, sizeof(std::complex < float > ) * uPwLen);

            unsigned int m_uSubPtLen = 0;
            for (int n = 0; n < 1; n++)//针对每个子脉冲计算相位、多普勒和波束调制系数
            {
                fSubFrFre = m_fSubFrFre * 1e6;            //子发射频率，单位：MHz
                fSubFrPt = m_fSubFrPt * 1e-6;            //子脉冲重复周期，单位：us
                fSubFrPw = m_fSubFrPw * 1e-6;            //子脉冲时宽，单位：us
                fSubTBeamAzi = 0;        //子脉冲发射波束指向方位（阵面坐标系），单位：弧度
                fSubTBeamEle = 0;        //子脉冲发射波束指向俯仰（阵面坐标系），单位：弧度

                m_uSubPtLen = floor(fFrFs * fSubFrPt);        //子脉冲重周长度
                floor(fFrFs * fSubFrPw);        //子脉冲脉冲长度

                CalcuRBeamCoe(&RBeamTemp, BeamCoePara, m_uBwBeamNum, fSubFrFre, fSubTBeamAzi, fSubTBeamEle, 0, 0,
                              &RBeamCoe);
                fTPhase = 2 * Pi * fSubFrFre *
                          (2 * fTargetVel * (fTotalTime + fSubTotalTime) / C_Speed);//exp(-j*2*pi*FrePoint*tm)
                TPhaseCell = ComplexExp(fTPhase);//计算不同脉冲的初始相位
                TPhaseCell.real(TPhaseCell.real() * fTargetAmp);//相位加权系数乘以目标幅度值
                TPhaseCell.imag(TPhaseCell.imag() * fTargetAmp);
                for (int k = 0; k < m_uBwBeamNum; k++)//指向目标的波束，和差差或多波束
                {
                    ComplexMul(TPhaseCell, RBeamCoe, (std::complex < float > *) & BeamPhase);    //计算不同波束的加权系数与相位乘积
                }
                fTFd = 2 * Pi * (2 * fTargetVel * fSubFrFre / C_Speed) / fFrFs;//多普勒频率(单位：Hz),exp(j*2*pi*Fd.*t);
                ComplexMExp(fTFd, m_uSubPtLen, TFdCoeAddr + uMSubPtLen);//产生多普勒调制系数数组

                uMSubPtLen = uMSubPtLen + m_uSubPtLen;
                fSubTotalTime = fSubTotalTime + fSubFrPt;
            }

            fTotalTime = fTotalTime + fFrPt;                    //时间累加

            ComplexPMul(WorkSig, TFdCoeAddr, uPwLen, WorkSig);    //目标回波与多普勒调制系数进行点乘
            for (int k = 0; k < m_uBwBeamNum; k++)//指向目标的波束，和差差或多波束
            {
                uMSubPtLen = 0;

                for (int n = 0; n < uSubFrNum; n++)//每个波束的对应子脉冲系数相乘
                {
                    ComplexCPMul(BeamPhase, WorkSig + uMSubPtLen, m_uSubPtLen,
                                 EchoData0Addr + uMSubPtLen);//目标回波乘以（相位调制与角度调制）复合调制系数

                    uMSubPtLen = uMSubPtLen + m_uSubPtLen;
                }
                //不同散射点信号叠加,===============================多散射点叠加错误
                memset(TFdCoeAddr, 0, uPtLen * sizeof(std::complex < float > ));
                int maxZeroLen = 0;
                for (int m = 0; m < 1; m++)//多散射点回波叠加
                {
                    ZeroLen = uScatter_FsCellDelayNum[m];//赋零长度
                    if (ZeroLen > maxZeroLen) {
                        maxZeroLen = ZeroLen;
                    }
                    int randnum = rand() % 2000;

                    std::complex<float> tempDelay;
                    tempDelay.imag(Scatter_PhaseDelay[m].imag());
                    tempDelay.real(Scatter_PhaseDelay[m].real());
                    if (rcs_type == 2 || rcs_type == 4) {
                        tempDelay.imag(tempDelay.imag() * rcsswerling[randnum]);
                        tempDelay.real(tempDelay.real() * rcsswerling[randnum]);
                    }

                    for (int n = 0; n < uPwLen; n++) {
                        TFdCoeAddr[ZeroLen + n] = TFdCoeAddr[ZeroLen + n] + Scatter_PhaseDelay[m] * EchoData0Addr[n];
                    }
                }
                //拷贝变叠加
                ComplexCAdd(TFdCoeAddr, m_uBwBeamNum, uPwLen + maxZeroLen, pOut + uModifyAddr + uTargetCell * 0 + k);
            }
            uModifyAddr = uModifyAddr + uPtLen * m_uBwBeamNum;//回波存储修正地址
        }
    }
    return uModifyAddr;
}

int Rasp_Simu::CalcuEchoLen() {
    int DataLen = 0;                                                            //回波长度
    float fFrPt = 0;                                                            //脉冲重复周期，单位：us
    float fFrFs = 0;                                                            //子脉冲采样带宽，单位：MHz
    unsigned int uPtLen = 0;                                                    //重周长度
    for (int i = 0; i < m_CpiNum; i++)                            //脉组循环
    {
        fFrPt = m_fFrPt;                        //单位：us
        fFrFs = m_fFrFs;                        //单位：MHz
        uPtLen = floor(fFrFs * fFrPt);                                        //重复周期采样单元数(1us*1MHz = 1)
        DataLen = DataLen + uPtLen * m_uBwBeamNum * m_uFrNum;    //数据长度累加
    }
    return DataLen;
}

void Rasp_Simu::CalcuRBeamCoe(DBF_RBEAM_STRUCT *RBeam, PARA_BEAMCOE_STRUCT BeamCoePara, unsigned int uBwBeamNum,
                              float fFrFre, float fTBeamAzi, float fTBeamEle, float fTargetAzi, float fTargetEle,
                              std::complex<float> *RBeamCoe) {
    float WaveLen = C_Speed / fFrFre;
    std::complex<float> TBeamCoe;
    memset(RBeamCoe, 0, sizeof(std::complex < float > ) * uBwBeamNum);
    for (int i = 0; i < uBwBeamNum; i++)    //波束循环
    {
        //计算接收波束UV空间坐标
        float fRDelU = (sin(fTargetAzi) * cos(fTargetEle) -
                        sin(RBeam[i].fRBeamAzi + fTBeamAzi) * cos(RBeam[i].fRBeamEle + fTBeamEle)) / WaveLen;
        float fRDelV = (sin(fTargetEle) - sin(RBeam[i].fRBeamEle + fTBeamEle)) / WaveLen;
        //接收U-V空间差值
        float fRUCoe = (BeamPointNum - 1) / 2 + floor(1.0 / BeamInterval * fRDelU);
        float fRVCoe = (BeamPointNum - 1) / 2 + floor(1.0 / BeamInterval * fRDelV);
        unsigned int uUAddr = (int) fRUCoe;
        unsigned int uVAddr = (int) fRVCoe;
        if ((uUAddr >= 0) && (uUAddr <= BeamPointNum) && (uVAddr >= 0) && (uVAddr <= BeamPointNum))//在系数范围
        {
            if (RBeam[i].uRBeamType == 0) {
                ComplexMul(BeamCoePara.SAziRBeamAmp[uUAddr], BeamCoePara.SEleRBeamAmp[uVAddr], RBeamCoe + i);
            }//和波束方位向方向图系数
            else if (RBeam[i].uRBeamType == 1) {
                ComplexMul(BeamCoePara.DAziRBeamAmp[uUAddr], BeamCoePara.SEleRBeamAmp[uVAddr], RBeamCoe + i);
            }//方位差波束方向图系数
            else if (RBeam[i].uRBeamType == 2) {
                ComplexMul(BeamCoePara.SAziRBeamAmp[uUAddr], BeamCoePara.DEleRBeamAmp[uVAddr], RBeamCoe + i);
            }//俯仰差波束方向图系数
            else if (RBeam[i].uRBeamType == 3) {
                ComplexMul(BeamCoePara.SLBAziBeamAmp[uUAddr], BeamCoePara.SLBEleBeamAmp[uVAddr], RBeamCoe + i);
            }//匿影波束方向图系数
            else {
                ComplexMul(BeamCoePara.SAziRBeamAmp[uUAddr], BeamCoePara.SEleRBeamAmp[uVAddr], RBeamCoe + i);
            }//其它按和波束方向图系数
        }
        //计算发射波束UV空间坐标
        float fTDelU = (sin(fTargetAzi) * cos(fTargetEle) - sin(fTBeamAzi) * cos(fTBeamEle)) / WaveLen;
        float fTDelV = (sin(fTargetEle) - sin(fTBeamEle)) / WaveLen;
        //发射U-V空间坐标
        float fTUCoe = (BeamPointNum - 1) / 2 + floor(1.0 / BeamInterval * fTDelU);
        float fTVCoe = (BeamPointNum - 1) / 2 + floor(1.0 / BeamInterval * fTDelV);
        uUAddr = (int) fTUCoe;
        uVAddr = (int) fTVCoe;
        //波束类型0~2的接收波束与发射波束调制系数相乘
        if ((RBeam[i].uRBeamType == 0) || (RBeam[i].uRBeamType == 1) || (RBeam[i].uRBeamType == 2)) {
            //指向目标的接收波束(和差差或多波束)调制系数与发射波束调制系数相复乘
            if ((uUAddr >= 0) && (uUAddr <= BeamPointNum) && (uVAddr >= 0) && (uVAddr <= BeamPointNum))//在系数范围
            {
                ComplexMul(BeamCoePara.SAziTBeamAmp[uUAddr], BeamCoePara.SEleTBeamAmp[uVAddr], &TBeamCoe);
                ComplexMul(TBeamCoe, RBeamCoe[i], RBeamCoe + i);
            } else {
                memset(&RBeamCoe[i], 0, sizeof(std::complex < float > ));
            }
        }
    }
}

int Rasp_Simu::ComplexCAdd(std::complex<float> *Ain, int ModifyAddr, int ComplexLen, std::complex<float> *Cout) {
    std::complex<float> a(1.0f, 0.0f);
    int incAin = 1;
    cblas_caxpy(ComplexLen, reinterpret_cast<float*>(&a), reinterpret_cast<float*>(Ain), incAin, reinterpret_cast<float*>(Cout), ModifyAddr);
    return 1;
}

void Rasp_Simu::ComplexCPMul(std::complex<float> Ain, std::complex<float> *Bin, unsigned int DataLen,
                             std::complex<float> *Cout) {
    for (int i = 0; i < DataLen; i++) {
        ComplexMul(Ain, Bin[i], Cout + i);
    }
}

std::complex<float> Rasp_Simu::ComplexExp(float in) {
    std::complex<float> out(cos(in), sin(in));
    return out;
}

void Rasp_Simu::ComplexMExp(float in, unsigned int DataLen, std::complex<float> *out) {
    for (int i = 0; i < DataLen; i++) {
        out[i] = ComplexExp(in * i);
    }
}

void Rasp_Simu::ComplexMul(std::complex<float> Ain, std::complex<float> Bin, std::complex<float> *Cout) {
    Cout->real(Ain.real() * Bin.real() - Ain.imag() * Bin.imag());
    Cout->imag(Ain.real() * Bin.imag() + Ain.imag() * Bin.real());//虚部
}

void Rasp_Simu::ComplexPMul(std::complex<float> *Ain, std::complex<float> *Bin, unsigned int DataLen,
                            std::complex<float> *Cout) {
    for (int i = 0; i < DataLen; i++) {
        ComplexMul(Ain[i], Bin[i], Cout + i);
    }
}

int Rasp_Simu::Gen_WorkSig(std::complex<float> *pOut) {
    unsigned int uSigAdrModify = 0;
    unsigned int SubFrPtLen;//子脉冲周期长度
    float fSubFrPt, fSubFrPw, fSubFrBw, fSubFrFs;
    for (int i = 0; i < 1; i++) {
        fSubFrPt = m_fSubFrPt * 1e-6;
        fSubFrFs = m_fSubFrFs * 1e6;
        SubFrPtLen = floor(fSubFrPt * fSubFrFs);
        uSigAdrModify = uSigAdrModify + SubFrPtLen;
    }
    memset(pOut, 0, sizeof(std::complex < float > ) * uSigAdrModify);
    uSigAdrModify = 0;

    unsigned int uSubFrType;
    unsigned int WorkSigLen;            //工作信号长度
    float fphase, fFreStep;
    float fTimeNo, fTimeModify;            //时间步进
    unsigned int uSubFrNum;//子脉冲数目
    uSubFrNum = 1;//子脉冲数目

    for (int i = 0; i < uSubFrNum; i++) {
        uSubFrType = m_uSubFrType;        //信号类型
        //载频，单位：Hz
        fSubFrPt = m_fSubFrPt * 1e-6;    //重周
        fSubFrPw = m_fSubFrPw * 1e-6;    //时宽，单位：s
        fSubFrBw = m_fSubFrBw * 1e6;        //带宽，单位：Hz
        fSubFrFs = m_fSubFrFs * 1e6;        //采样率，单位：Hz
        WorkSigLen = floor(fSubFrPw * fSubFrFs);
        SubFrPtLen = floor(fSubFrPt * fSubFrFs);

        float ACoe[10] = {1.496272e-1, 4.725035e-2, 2.039086e-2, 8.280490e-3, 3.357491e-3, 4.255462e-3, 1.036288e-3,
                          4.101056e-4, 4.930347e-4, 5.457094e-4};
        int ACoe_Len = 10;
        int CodeNum = floor(fSubFrPw * fSubFrBw);
        int Coderepmat = floor(fSubFrFs / fSubFrBw);

        if ((uSubFrType == 0) || (uSubFrType == 1) || (uSubFrType == 2))    //产生线性调频，正-负-双线性调频
        {
            if (uSubFrType == 0) {
                fFreStep = Pi * (fSubFrBw / fSubFrPw) / pow(fSubFrFs, 2);    //正频率步进
                fTimeModify = 0.5 - float(WorkSigLen) / 2.0;
            } else if (uSubFrType == 1) {
                fFreStep = -Pi * (fSubFrBw / fSubFrPw) / pow(fSubFrFs, 2);    //负频率步进
                fTimeModify = 0.5 - float(WorkSigLen) / 2.0;
            } else if (uSubFrType == 2) {
                fFreStep = Pi * (fSubFrBw / fSubFrPw) / pow(fSubFrFs, 2);    //三角频率步进（未分正负三角）
                fTimeModify = float(WorkSigLen) / 2.0 - 0.5;
            }
            for (int j = 0; j < WorkSigLen; j++) {
                if (uSubFrType == 0) { fTimeNo = j + fTimeModify; }
                else if (uSubFrType == 1) { fTimeNo = j + fTimeModify; }
                else if (uSubFrType == 2) {
                    if (j < fTimeModify) { fTimeNo = j; }
                    else { fTimeNo = 2 * fTimeModify - j; }
                }
                fphase = fFreStep * pow(fTimeNo, 2);
                pOut[uSigAdrModify + j] = ComplexExp(fphase);
            }
        } else if (uSubFrType == 3)//非线性调频信号
        {
            GenNLFMSig(1.0, 0, fSubFrPw, fSubFrBw, fSubFrFs, 0, ACoe, pOut + uSigAdrModify, ACoe_Len);
        } else if (uSubFrType == 4)//二相编码信号
        {
            Gen2PnSig(1.0, 0, CodeNum, Coderepmat, pOut + uSigAdrModify);
        } else if (uSubFrType == 5)//四相编码信号
        {
            Gen4PnSig(1.0, 0, CodeNum, Coderepmat, pOut + uSigAdrModify);
        } else            //点频信号
        {
            GenPFSig(1.0, fSubFrPw, fSubFrFs, 0, 0, pOut + uSigAdrModify);
        }
        uSigAdrModify = uSigAdrModify + SubFrPtLen;
    }
    return uSigAdrModify;
}

int Rasp_Simu::Gen2PnSig(float fApm, int DelayLen, int CodeNum, int Coderepmat, std::complex<float> *pOut) {
    int SCodeNum = 1024;
    bool spn[18];
    bool sn1, sn2, pn;
    memset(&spn[1], 0, sizeof(bool) * 18 - 1);
    spn[0] = true;
    for (int i = 0; i < SCodeNum; i++)//从SCodeNum开始取码元
    {
        sn1 = spn[17] ^ spn[4];
        sn2 = sn1 ^ spn[6];
        pn = sn2 ^ spn[9];
        memmove(&spn[1], &spn[0], sizeof(bool) * 17);
        spn[0] = pn;
    }
    for (int i = 0; i < CodeNum; i++)//从SCodeNum开始取码元
    {
        sn1 = spn[17] ^ spn[4];
        sn2 = sn1 ^ spn[6];
        pn = sn2 ^ spn[9];
        memmove(&spn[1], &spn[0], sizeof(bool) * 17);
        spn[0] = pn;
        //fix by zdd 20190515
        float coe = 1.0;
        if (pn == 0) {
            coe = -1.0;
        }
        coe = fApm * coe;

        std::complex<float> tempdata(coe, 0.0);
        std::fill(pOut + i * Coderepmat + DelayLen, pOut + i * Coderepmat + Coderepmat + DelayLen, tempdata);
    }
    return Coderepmat * CodeNum;
}

int Rasp_Simu::Gen4PnSig(float fApm, int DelayLen, int CodeNum, int Coderepmat, std::complex<float> *pOut) {
    int SCodeNum = 1024;
    bool spn[18];
    bool sn1, sn2, pn;
    memset(&spn[1], 0, sizeof(bool) * 18 - 1);
    spn[0] = true;
    for (int i = 0; i < SCodeNum; i++)//从SCodeNum开始取码元
    {
        sn1 = spn[17] ^ spn[4];
        sn2 = sn1 ^ spn[6];
        pn = sn2 ^ spn[9];
        memmove(&spn[1], &spn[0], sizeof(bool) * 17);
        spn[0] = pn;
    }
    int PhModify;
    int code;
    float PhReal = 0.0, PhImag = 0.0;
    for (int i = 0; i < CodeNum; i++)//从SCodeNum开始取码元
    {
        sn1 = spn[17] ^ spn[4];
        sn2 = sn1 ^ spn[6];
        pn = sn2 ^ spn[9];
        memmove(&spn[1], &spn[0], sizeof(bool) * 17);
        spn[0] = pn;
        if (pn == 0) {
            code = -1;
        } else {
            code = 1;
        }
        if (i > 0) {
            PhModify = abs((-(-1) * (-i + 1)) % 4);//求余数
            if (PhModify == 1) {
                PhReal = 0;
                PhImag = -code * fApm;
            } else if (PhModify == 2) {
                PhReal = -code * fApm;
                PhImag = 0;
            } else if (PhModify == 3) {
                PhReal = 0;
                PhImag = code * fApm;
            } else {
                PhReal = code * fApm;
                PhImag = 0;
            }
        }
        std::complex<float> tempdata(PhReal, PhImag);
        std::fill(pOut + i * Coderepmat + DelayLen, pOut + i * Coderepmat + Coderepmat + DelayLen, tempdata);
    }
    return Coderepmat * CodeNum;
}

int Rasp_Simu::GenNLFMSig(float fApm, int DelayLen, float Pw, float Bw, float Fs, int ModuDir, float *ACoe,
                          std::complex<float> *pOut, int ACoe_Len) {
    int i, j;
    float t, Ts;
    Ts = 1 / Fs;
    int PwLen = (int) (Pw * Fs);
    float phsum = 0.0;
    float ft;
    float ASA;
    for (int i = 0; i < PwLen; i++) {
        ASA = 0.0;
        t = Ts / 2 + i * Ts;
        for (int j = 0; j < ACoe_Len; j++) {
            ASA = ASA + ACoe[j] * sin(2 * Pi * (j + 1) * t / Pw);
        }
        ft = Bw * (t / Pw + ASA) - Bw / 2;
        if (ModuDir == 0) {
            phsum = phsum + ft * Ts;
        } else {
            phsum = phsum - ft * Ts;
        }
        pOut[i + DelayLen] = ComplexExp(2 * Pi * phsum);
        pOut[i + DelayLen] *= fApm;
    }
    return PwLen;
}

int Rasp_Simu::GenPFSig(float fApm, float Pw, float Fs, float F0, int DelayLen, std::complex<float> *pOut) {
    int PwLen = (int) (Pw * Fs);
    float ft;
    for (int i = 0; i < PwLen; i++) {
        ft = i * F0 / Fs;
        pOut[DelayLen + i] = ComplexExp(ft);
        pOut[DelayLen + i] *= fApm;
    }
    return PwLen;
}